/*
 * delay.c
 *
 *  Created on: Jul 14, 2024
 *      Author: 废话文学创始人
 */

#include <delay.h>

#define us (HAL_RCC_GetSysClockFreq()/1000000)

/**
 * DWT使能，并开始计数
 * 说明：使用由DWT产生的delay函数前需要使用此函数进行硬件初始化
 */
void DWT_init(void)
{
	//使能DWT
	CoreDebug->DEMCR = (CoreDebug->DEMCR&(~CoreDebug_DEMCR_TRCENA_Msk))|
			((1U<<CoreDebug_DEMCR_TRCENA_Pos)&CoreDebug_DEMCR_TRCENA_Msk);
	//清空CYC计数寄存器的值
	DWT->CYCCNT = (uint32_t)0u;
	//启用CYC计时器
	DWT->CTRL = (DWT->CTRL&(~DWT_CTRL_CYCCNTENA_Msk))|
			((1U<<DWT_CTRL_CYCCNTENA_Pos)&DWT_CTRL_CYCCNTENA_Msk);
}
/**
 * 使用DWT的阻塞us级延时
 * 有效值：1~(2^32/us)
 * 误差说明：多1us左右
 */
void HAL_DWT_Delay_us(uint32_t nus)
{
	//初始值记录
	uint32_t count_start = DWT->CYCCNT;
	//计数次数计算
	uint32_t count_nus = nus*us;
	//目标计数值
	uint32_t count_end = count_start+count_nus;
	//计数到目标值
	if(count_end>count_start){
		while(DWT->CYCCNT<count_end);
	}else{
		while(DWT->CYCCNT>count_end);
		while(DWT->CYCCNT<count_end);
	}
}
/**
 * 使用DWT的阻塞ms级延时
 * 有效值：1~2^32
 */
void HAL_DWT_Delay_ms(uint32_t nms)
{
	for(int i = 0;i < nms;i++){
		HAL_DWT_Delay_us(1000);
	}
}

